package com.wtp.wallpaper.es.service;

import cn.hutool.core.bean.BeanUtil;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.core.BulkRequest;
import co.elastic.clients.elasticsearch.core.UpdateRequest;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wtp.wallpaper.es.Repository.PictureDocumentRepository;
import com.wtp.wallpaper.es.document.PictureDocument;
import com.wtp.wallpaper.pojo.entity.Picture;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static co.elastic.clients.elasticsearch._types.GeoLocation.Kind.Text;

@Service
@Slf4j
public class PictureDocumentService {

    @Autowired
    private PictureDocumentRepository pictureDocumentRepository;

    @Autowired
    private ElasticsearchClient client;

    private static final ObjectMapper objectMapper = new ObjectMapper();

    static {
        // 配置ObjectMapper忽略null值
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    }

    // 根据 ID 获取文档
    public PictureDocument getDocument(String id) {
        return pictureDocumentRepository.findById(Long.valueOf(id)).orElse(null);
    }

    public void save(Picture picture){
        PictureDocument pictureDocument = BeanUtil.copyProperties(picture, PictureDocument.class);
        log.info("添加{}到es中",pictureDocument);
        pictureDocumentRepository.save(pictureDocument);
    }

    public void saveAll(List<PictureDocument> pictures){
        if(pictures.isEmpty()) return;
        BulkRequest.Builder bulkRequest = new BulkRequest.Builder();
        for (PictureDocument doc : pictures) {
            bulkRequest.operations(op -> op
                    .index(idx -> idx
                            .index("picture")
                            .id(doc.getId().toString())
                            .document(objectMapper.convertValue(doc, Map.class))
                    )
            );
        }

        // 提交批量请求（异步非阻塞）
        try {
            client.bulk(bulkRequest.build());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        //pictureDocumentRepository.saveAll(pictures);
    }

    public void deleteByIds(List<Long> ids){
        pictureDocumentRepository.deleteAllById(ids);
    }

    public void update(Picture picture){
        PictureDocument pictureDocument = BeanUtil.copyProperties(picture, PictureDocument.class);
        update(pictureDocument);
    }

    public void update(PictureDocument pictureDocument){

        String index = "picture";
        String docId = String.valueOf(pictureDocument.getId());
        // 将对象转换为过滤空值的Map
        Map<String, Object> params = convertToNonNullMap(pictureDocument);

        UpdateRequest<Object, Object> updateRequest = UpdateRequest.of(builder -> builder
                .id(docId)
                .index(index)
                .doc(params));

        try {
            PictureDocument document = getDocument(docId);
            if (document != null){
                client.update(updateRequest, Object.class);
            }else{
                log.info("es中不存在该数据，添加：{}",pictureDocument);
                pictureDocumentRepository.save(pictureDocument);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public List<Long> searchPicturesByTabsAndDescription(String keyword) {
        // 通过Elasticsearch模糊查询获取匹配的文档
        List<PictureDocument> esResults = pictureDocumentRepository.searchByDescriptionAndTabs(keyword);
        log.info("es查询：{}",esResults);
        // 提取文档中的ID
        return esResults.stream().map(PictureDocument::getId).toList();
    }

    public List<PictureDocument> search(String keyword) {
        List<SearchHit<PictureDocument>> results = pictureDocumentRepository.findByDescriptionContaining(keyword);
        //return results.stream().map(SearchHit::getContent).toList();

        return results.stream()
                .map(hit -> {
                    // 获取原始文档对象
                    PictureDocument doc = hit.getContent();

                    // 处理description字段高亮
                    if (hit.getHighlightFields().containsKey("description")) {
                        List<String> highlights = hit.getHighlightFields().get("description")
                                .stream()
                                .toList();

                        // 取第一个高亮片段覆盖原字段（或自定义合并逻辑）
                        if (!highlights.isEmpty()) {
                            doc.setDescription(highlights.get(0));
                        }
                    }

                    return doc;
                })
                .collect(Collectors.toList());
    }

    private Map<String, Object> convertToNonNullMap(Object obj) {
        return objectMapper.convertValue(obj, new TypeReference<Map<String, Object>>() {});
    }
}
